﻿namespace Services
{
    public interface ILogic<TModel, TFilterModel>
        where TModel : BaseModel
        where TFilterModel : BaseFilterModel
    {
        #region 添加
        TModel Insert(TModel model);
        int BatchInsert(List<TModel> models);
        #endregion

        #region 修改
        int Update(TModel model);
        int BatchUpdate(List<TModel> models);
        #endregion

        #region 删除
        int Delete(int id);
        int BatchDelete(List<int> ids);
        #endregion

        #region 查询
        TModel GetByID(int id);
        TModel GetModel(TFilterModel filterModel, string orderBy = null);
        List<TModel> GetAll(string orderBy = null);
        List<TModel> GetSearch(TFilterModel filterModel, string orderBy = null, int? top = null);
        PageModel<TModel> GetPage(TFilterModel filterModel, int pageIndex = 1, int pageSize = Gx._PAGE_SIZE, string orderBy = null);
        int GetCount(TFilterModel filterModel);
        #endregion
    }

    public class BaseLogic<TModel, TFilterModel, TEntity, TIRepository, TIMapping, TIService> : ILogic<TModel, TFilterModel>
        where TModel : BaseModel
        where TFilterModel : BaseFilterModel
        where TEntity : BaseEntity, new()
        where TIRepository : IRepository<TEntity>
        where TIMapping : IMapping<TEntity, TModel, TFilterModel>
        where TIService : IService
    {
        #region Ioc
        public readonly ICurrentUser _currentUser;
        public readonly TIRepository _repository;
        public readonly TIMapping _mapping;
        public readonly TIService _service;

        public BaseLogic(ICurrentUser currentUser, TIRepository repository, TIMapping mapping, TIService service)
        {
            _currentUser = currentUser;
            _repository = repository;
            _mapping = mapping;
            _service = service;
        }
        #endregion

        #region 添加
        public virtual TModel Insert(TModel model)
        {
            var id = _repository.Insert(_mapping.Model2Entity(model));
            return GetByID(id);
        }

        public virtual int BatchInsert(List<TModel> models)
        {
            return _repository.BatchInsert(_mapping.Model2Entity(models));
        }
        #endregion

        #region 修改
        public virtual int Update(TModel model)
        {
            return _repository.Update(_mapping.Model2Entity(model));
        }

        public virtual int BatchUpdate(List<TModel> models)
        {
            return _repository.BatchUpdate(_mapping.Model2Entity(models));
        }
        #endregion

        #region 删除
        public virtual int Delete(int id)
        {
            return _repository.Delete(id);
        }

        public virtual int BatchDelete(List<int> ids)
        {
            return _repository.BatchDelete(ids);
        }
        #endregion

        #region 查询
        public virtual TModel GetByID(int id)
        {
            return _mapping.Entity2Model(_repository.GetByID(id));
        }

        public virtual TModel GetModel(TFilterModel filterModel, string orderBy = null)
        {
            return _mapping.Entity2Model(_repository.GetModel(_mapping.FilterModel2Where(filterModel), orderBy));
        }

        public virtual List<TModel> GetAll(string orderBy = null)
        {
            return _mapping.Entity2Model(_repository.GetAll(orderBy));
        }

        public virtual List<TModel> GetSearch(TFilterModel filterModel, string orderBy = null, int? top = null)
        {
            return _mapping.Entity2Model(_repository.GetSearch(_mapping.FilterModel2Where(filterModel), orderBy, top));
        }

        public virtual PageModel<TModel> GetPage(TFilterModel filterModel, int pageIndex = 1, int pageSize = 20, string orderBy = null)
        {
            PageModel<TModel> pageResult = new();

            var where = _mapping.FilterModel2Where(filterModel);

            var (items, totalCount) = _repository.GetPage(where, pageIndex, pageSize, orderBy);
            pageResult.Items = _mapping.Entity2Model(items);
            pageResult.TotalCount = totalCount;

            return pageResult;
        }

        public virtual int GetCount(TFilterModel filterModel)
        {
            return _repository.GetCount(_mapping.FilterModel2Where(filterModel));
        }
        #endregion
    }
}
